<!--
    日期组件
    Taoxin    2016-05-18
    @params   
-->

<template>
  <div class="cov-vue-date">
    <div class="datepickbox">
      <input
        type="text"
        title="input date"
        class="cov-datepicker form-control"
        placeholder="{{option.placeholder}}"
        v-model="time"
        :required="required"
        @click="showCheck"
        :style="option.inputStyle"/>
    </div>

    <div class="datepicker-overlay"
         v-if="showInfo.check"
         @click="dismiss($event)"
         v-bind:style="{'background' : option.overlayOpacity? 'rgba(0,0,0,'+option.overlayOpacity+')' : 'rgba(0,0,0,0.5)'}">
      <div
        class="cov-date-body"
        :style="{'background-color': option.color ? option.color.header : '#3f51b5'}">
        <div class="cov-date-monthly">
          <div class="cov-date-previous" @click="nextMonth('pre')">«</div>
          <div class="cov-date-caption" :style="{'color': option.color ? option.color.headerText : '#fff'}">
            <span @click="showYear"><small>{{checked.year}}</small></span>
            <br>
            <span @click="showMonth">{{displayInfo.month}}</span>
          </div>
          <div class="cov-date-next" @click="nextMonth('next')">»</div>
        </div>
        <div class="cov-date-box" v-if="showInfo.day">
          <div class="cov-picker-box">
            <div class="week">
              <ul>
                <li v-for="weekie in library.week">{{weekie}}</li>
              </ul>
            </div>
            <div
              class="day"
              v-for="day in dayList"
              track-by="$index"
              @click="checkDay(day)"
              :class="{'checked':day.checked,'unavailable':day.unavailable,'passive-day': !(day.inMonth)}"
            >{{day.value}}
            </div>
          </div>
        </div>
        <div class="cov-date-box list-box" v-if="showInfo.year">
          <div class="cov-picker-box date-list" id="yearList">
            <div class="date-item" v-for="yearItem in library.year" track-by="$index" @click="setYear(yearItem)">
              {{yearItem}}
            </div>
          </div>
        </div>
        <div class="cov-date-box list-box" v-if="showInfo.month">
          <div class="cov-picker-box date-list">
            <div class="date-item" v-for="monthItem in library.month" track-by="$index" @click="setMonth(monthItem)">
              {{monthItem}}
            </div>
          </div>
        </div>
        <div class="cov-date-box list-box" v-if="showInfo.hour">
          <div class="cov-picker-box date-list">
            <div class="watch-box">
              <div class="hour-box">
                <div class="mui-pciker-rule mui-pciker-rule-ft"></div>
                <ul>
                  <li
                    class="hour-item"
                    v-for="hitem in hours"
                    @click="setTime('hour', hitem, hours)"
                    :class="{'active':hitem.checked}"
                  >{{hitem.value}}
                  </li>
                </ul>
              </div>
              <div class="min-box">
                <div class="mui-pciker-rule mui-pciker-rule-ft"></div>
                <div
                  class="min-item"
                  v-for="mitem in mins"
                  @click="setTime('min',mitem, mins)"
                  :class="{'active':mitem.checked}"
                >{{mitem.value}}
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="button-box">
          <span @click="showInfo.check=false">{{option.buttons? option.buttons.cancel : 'Cancel' }}</span>
          <span @click="picked">{{option.buttons? option.buttons.ok : 'Ok'}}</span>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  import moment from 'moment';
  import _ from 'lodash';
  export default {
    props: {
      required: false,
      time: {
        type: String,
        required: true
      },
      option: {
        type: Object,
        default() {
          return {
            type: 'day',
            week: ['一', '二', '三', '四', '五', '六', '日'],
            month: ['一月', '二月', '三月', '四月', '五月',
              '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
            format: 'YYYY-MM-DD HH:mm',
            color: {
              header: '#3f51b5',
              headerText: '#fff'
            },
            inputStyle: {
              display: 'inline-block',
              padding: '6px',
              lineHeight: '22px',
              fontSize: '16px',
              border: '2px solid #fff',
              boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.2)',
              borderRadius: '2px',
              color: '#5F5F5F'
            },
            placeholder: 'when?',
            buttons: {
              ok: 'Ok',
              cancel: 'Cancel'
            },
            overlayOpacity: 0.5,
            dismissible: true
          };
        }
      },
      limit: {
        type: Array,
        default() {
          return [];
        }
      }
    },
    data() {
      function hours() {
        const list = [];
        let hour = 24;
        while (hour > 0) {
          hour--;

          list.push({
            checked: false,
            value: hour < 10 ? '0' + hour : hour
          });
        }
        return list;
      }

      function mins() {
        const list = [];
        let min = 60;
        while (min > 0) {
          min--;
          list.push({
            checked: false,
            value: min < 10 ? '0' + min : min
          });
        }
        return list;
      }

      return {
        hours: hours(),
        mins: mins(),
        showInfo: {
          hour: false,
          day: false,
          month: false,
          year: false,
          check: false
        },
        displayInfo: {
          month: ''
        },
        library: {
          week: this.option.week,
          month: this.option.month,
          year: []
        },
        checked: {
          oldtime: '',
          currentMoment: null,
          year: '',
          month: '',
          day: '',
          hour: '00',
          min: '00'
        },
        dayList: []
      };
    },
    methods: {
      nextMonth(type) {
        let next = null;

        type === 'next' ? next = moment(this.checked.currentMoment).add(1, 'M') : next
          = moment(this.checked.currentMoment).add(-1, 'M');

        this.showDay(next);
      },
      showDay(time) {
        if (time === undefined || !Date.parse(time)) {
          this.checked.currentMoment = moment();
        } else {
          this.checked.currentMoment = moment(time, this.option.format);
        }
        this.showOne('day');

        this.checked.year = moment(this.checked.currentMoment).format('YYYY');
        this.checked.month = moment(this.checked.currentMoment).format('MM');
        this.checked.day = moment(this.checked.currentMoment).format('DD');

        this.displayInfo.month = this.library.month[moment(this.checked.currentMoment).month()];

        let days = [];
        const currentMoment = this.checked.currentMoment;
        let firstDay = moment(currentMoment).date(1).day();
//        console.log(firstDay)

        const currentMonth = _.cloneDeep(currentMoment);
        const previousMonth = _.cloneDeep(currentMoment);
        const nextMonth = _.cloneDeep(currentMoment);
        nextMonth.add(1, 'months');
        previousMonth.subtract(1, 'months');

        const monthDays = moment(currentMoment).daysInMonth();
        const oldtime = this.checked.oldtime;
        for (let i = 1; i <= monthDays; ++i) {
          days.push({
            value: i,
            inMonth: true,
            unavailable: false,
            checked: false
          });
          if (i === Math.ceil(moment(currentMoment).format('D')) && moment(oldtime).year()
            === moment(currentMoment).year() && moment(oldtime).month()
            === moment(currentMoment).month()) {
            days[i - 1].checked = true;
          }
        }

        if (firstDay === 0) firstDay = 7;

        for (let i = 0; i < firstDay - 1; i++) {
          const passiveDay = {
            value: previousMonth.daysInMonth() - (i),
            inMonth: false,
            action: 'previous',
          };
          days.unshift(passiveDay);
        }

        if (this.limit.length > 0) {
          for (const li of this.limit) {
            switch (li.type) {
              case 'fromto':
                days = this.limitFromTo(li, days);
                break;
              case 'weekday':
                days = this.limitWeekDay(li, days);
                break;
              default:

            }
          }
        }

        const passiveDaysAtFinal = 42 - days.length;
        for (let i = 1; i <= passiveDaysAtFinal; i++) {
          const passiveDay = {
            value: i,
            inMonth: false,
            action: 'next',
          };
          days.push(passiveDay);
        }
        this.dayList = days;
      },
      limitWeekDay(limit, days) {
        days.map((day) => {
          let tday;
        day.value < 10 ? tday = '0' + day.value : tday = day.value;

        if (limit.available.indexOf(Math.floor(moment(this.checked.year + '-' +
            this.checked.month + '-' + tday).format('d'))) === -1) {
          day.unavailable = true;
        }
        return this;
      });
        return days;
      },
      limitFromTo(limit, days) {
        days.map((day) => {
          if (!moment(this.checked.year + '-' + this.checked.month + '-' +
          day.value).isBetween(limit.from, limit.to)){
          day.unavailable = true;
          }
        return this;
        });
        return days;
      },
      checkDay(obj) {
        if (obj.unavailable || obj.value === '') {
          return false;
        }

        if (!(obj.inMonth)) {
          this.nextMonth(obj.action);
        }

        this.dayList.map(x => x.checked = false
      )
        ;
        obj.checked = true;
        this.checked.day = obj.value;
        this.checked.day.length < 2 ? this.checked.day = '0' + this.checked.day : this.checked.day;
        if (this.option.type === 'day') {
          this.picked();
        } else {
          this.showOne('hour');
        }
      },

      showYear() {
        const year = moment(this.checked.currentMoment).year();
        this.library.year = [];
        const yearTmp = [];
        for (let i = year - 100; i < year + 5; ++i) {
          yearTmp.push(i);
        }
        this.library.year = yearTmp;

        this.showOne('year');

        const self = this;
        this.$nextTick(() => function () {
          const listDom = document.getElementById('yearList');
          listDom.scrollTop = (listDom.scrollHeight - 100);
          self.addYear();
        });
      },
      showOne(type) {
        switch (type) {
          case 'year':
            this.showInfo.hour = false;
            this.showInfo.day = false;
            this.showInfo.year = true;
            this.showInfo.month = false;
            break;
          case 'month':
            this.showInfo.hour = false;
            this.showInfo.day = false;
            this.showInfo.year = false;
            this.showInfo.month = true;
            break;
          case 'day':
            this.showInfo.hour = false;
            this.showInfo.day = true;
            this.showInfo.year = false;
            this.showInfo.month = false;
            break;
          case 'hour':
            this.showInfo.hour = true;
            this.showInfo.day = false;
            this.showInfo.year = false;
            this.showInfo.month = false;
            break;
          default:
            this.showInfo.day = true;
            this.showInfo.year = false;
            this.showInfo.month = false;
            this.showInfo.hour = false;
            break;


        }
      },
      showMonth() {
        this.showOne('month');
      },
      addYear() {
        const self = this;
        const listDom = document.getElementById('yearList');
        const tmp = 0;
        listDom.addEventListener('scroll', () => function () {

          if (listDom.scrollTop < listDom.scrollHeight - 100) {
            const len = self.library.year.length;
            const lastYear = self.library.year[len - 1];
            self.library.year.push(lastYear + 1);
          }


        }, false);
      },
      setYear(year) {
        this.checked.currentMoment = moment(year + '-' + this.checked.month + '-' + this.checked.day);
        this.showDay(this.checked.currentMoment);
      },
      setMonth(month) {
        let mo = (this.library.month.indexOf(month) + 1);
        if (mo < 10) {
          mo = '0' + mo;
        }
        this.checked.currentMoment = moment(this.checked.year + '-' + mo + '-' + this.checked.day);
        this.showDay(this.checked.currentMoment);
      },
      showCheck() {
        if (this.time === '') {
          this.showDay();
        } else {
          this.checked.oldtime = this.time;
          this.showDay(this.time);
        }

        this.showInfo.check = true;
      },
      setTime(type, obj, list){
        for (const item of list) {
          item.checked = false;
          if (item.value === obj.value) {
            item.checked = true;
            this.checked[type] = item.value;
          }
        }
      },
      picked(){
        const ctime = this.checked.year + '-' + this.checked.month + '-' +
          this.checked.day + ' ' + this.checked.hour + ':' + this.checked.min;
        this.checked.currentMoment = moment(ctime, 'YYYY-MM-DD HH:mm');
        this.time = moment(this.checked.currentMoment).format(this.option.format);
        this.showInfo.check = false;
      },
      dismiss(evt){
        if (evt.target.className === 'datepicker-overlay') {
          if (this.option.dismissible === undefined || this.option.dismissible) {
            this.showInfo.check = false;
          }
        }
      }


    }
  };
</script>
<style scoped>
  .datepicker-overlay {
    position: fixed;
    width: 100%;
    height: 100%;
    z-index: 998;
    top: 0;
    left: 0;
    overflow: hidden;
    -webkit-animation: fadein 0.5s; /* Safari, Chrome and Opera > 12.1 */
    -moz-animation: fadein 0.5s; /* Firefox < 16 */
    -ms-animation: fadein 0.5s; /* Internet Explorer */
    -o-animation: fadein 0.5s; /* Opera < 12.1 */
    animation: fadein 0.5s;
  }

  @keyframes fadein {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  /* Firefox < 16 */
  @-moz-keyframes fadein {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  /* Safari, Chrome and Opera > 12.1 */
  @-webkit-keyframes fadein {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  /* Internet Explorer */
  @-ms-keyframes fadein {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  /* Opera < 12.1 */
  @-o-keyframes fadein {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  .cov-date-body {
    display: inline-block;
    background: #3F51B5;
    overflow: hidden;
    position: relative;
    font-size: 16px;
    font-family: 'Roboto';
    font-weight: 400;
    position: fixed;
    display: block;
    width: 400px;
    max-width: 100%;
    z-index: 999;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
  }

  .cov-picker-box {
    background: #fff;
    width: 100%;
    display: inline-block;
    padding: 25px;
    box-sizing: border-box !important;
    -moz-box-sizing: border-box !important;
    -webkit-box-sizing: border-box !important;
    -ms-box-sizing: border-box !important;
    width: 400px;
    max-width: 100%;
    height: 280px;
    text-align: start !important;
  }

  .cov-picker-box td {
    height: 34px;
    width: 34px;
    padding: 0;
    line-height: 34px;
    color: #000;
    background: #fff;
    text-align: center;
    cursor: pointer;
  }

  .cov-picker-box td:hover {
    background: #E6E6E6;
  }

  table {
    border-collapse: collapse;
    border-spacing: 0;
    width: 100%;
  }

  .day {
    width: 14.2857143%;
    display: inline-block;
    text-align: center;
    cursor: pointer;
    height: 34px;
    padding: 0;
    line-height: 34px;
    color: #000;
    background: #fff;
    vertical-align: middle;
  }

  .week ul {
    margin: 0 0 8px;
    padding: 0;
    list-style: none;
  }

  .week ul li {
    width: 14.2%;
    display: inline-block;
    text-align: center;
    background: transparent;
    color: #000;
    font-weight: bold;
  }

  .passive-day {
    color: #bbb;
  }

  .checked {
    background: #F50057;
    color: #FFF !important;
    border-radius: 3px;
  }

  .unavailable {
    color: #ccc;
    cursor: not-allowed;
  }

  .cov-date-monthly {
    height: 150px;
  }

  .cov-date-monthly > div {
    display: inline-block;
    padding: 0;
    margin: 0;
    vertical-align: middle;
    color: #fff;
    height: 150px;
    float: left;
    text-align: center;
    cursor: pointer;
  }

  .cov-date-previous,
  .cov-date-next {
    position: relative;
    width: 20% !important;
    text-indent: -300px;
    overflow: hidden;
    color: #fff;
  }

  .cov-date-caption {
    width: 60%;
    padding: 50px 0 !important;
    box-sizing: border-box;
    font-size: 24px;
  }

  .cov-date-caption span:hover {
    color: rgba(255, 255, 255, 0.7);
  }

  .cov-date-previous:hover,
  .cov-date-next:hover {
    background: rgba(255, 255, 255, 0.1);
  }

  .day:hover {
    background: #EAEAEA;
  }

  .unavailable:hover {
    background: none;
  }

  .checked:hover {
    background: #FF4F8E;
  }

  .cov-date-next::before,
  .cov-date-previous::before {
    width: 20px;
    height: 2px;
    text-align: center;
    position: absolute;
    background: #fff;
    top: 50%;
    margin-top: -7px;
    margin-left: -7px;
    left: 50%;
    line-height: 0;
    content: '';
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    transform: rotate(45deg);
  }

  .cov-date-next::after,
  .cov-date-previous::after {
    width: 20px;
    height: 2px;
    text-align: center;
    position: absolute;
    background: #fff;
    margin-top: 6px;
    margin-left: -7px;
    top: 50%;
    left: 50%;
    line-height: 0;
    content: '';
    -webkit-transform: rotate(-45deg);
    -moz-transform: rotate(-45deg);
    transform: rotate(-45deg);
  }

  .cov-date-previous::after {
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    transform: rotate(45deg);
  }

  .cov-date-previous::before {
    -webkit-transform: rotate(-45deg);
    -moz-transform: rotate(-45deg);
    transform: rotate(-45deg);
  }

  .date-item {
    text-align: center;
    font-size: 20px;
    padding: 10px 0;
    cursor: pointer;
  }

  .date-item:hover {
    background: #e0e0e0;
  }

  .date-list {
    overflow: auto;
    vertical-align: top;
    padding: 0;
  }

  .cov-datepicker {
    display: inline-block;
    padding: 6px;
    line-height: 22px;
    font-size: 16px;
    border: 2px solid #fff;
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
    border-radius: 2px;
    font-family: 'Roboto';
    color: #5F5F5F;
  }

  .cov-vue-date {
    display: inline-block;
    color: #5D5D5D;
  }

  .button-box {
    background: #fff;
    vertical-align: top;
    height: 50px;
    line-height: 50px;
    text-align: right;
    padding-right: 20px;
  }

  .button-box span {
    cursor: pointer;
    padding: 10px 20px;
  }

  .watch-box {
    height: 100%;
    overflow: hidden;
  }

  .hour-box,
  .min-box {
    display: inline-block;
    width: 50%;
    text-align: center;
    height: 100%;
    overflow: auto;
    float: left;
  }

  .hour-box ul,
  .min-box ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .hour-item, .min-item {
    padding: 10px;
    font-size: 36px;
    cursor: pointer;
  }

  .hour-item:hover, .min-item:hover {
    background: #E3E3E3;
  }

  .hour-box .active, .min-box .active {
    background: #F50057;
    color: #FFF !important;
  }

  ::-webkit-scrollbar {
    width: 2px;
  }

  ::-webkit-scrollbar-track {
    background: #E3E3E3;
  }

  ::-webkit-scrollbar-thumb {
    background: #C1C1C1;
    border-radius: 2px;
  }
</style>
